﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ClientSide
{
    #region Using

    using DevComponents.DotNetBar;
    using System.Net.Sockets;
    using System.Net;

    #endregion

    public partial class FrmConfiguration : Office2007Form
    {
        #region Variables

        /// <summary>
        /// Socket to receive and send data
        /// </summary>
        private AsyncSocket m_socClient = new AsyncSocket();

        /// <summary>
        /// Delegate to write log status
        /// </summary>
        /// <param name="data"></param>
        private delegate void WriteStatusDel(string data);

        /// <summary>
        /// Delgate to start game
        /// </summary>
        private delegate void StartGameDel();

        /// <summary>
        /// Delgate to start game
        /// </summary>
        private delegate void EnableStartGameDel(bool enable);

        #endregion

        public FrmConfiguration()
        {
            InitializeComponent();
            m_socClient.ConnectHandler += HandleSocketEvent;
        }

        /// <summary>
        /// When AsyncSocket object raises event handler, this routine will be called
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleSocketEvent(object sender, EventArgs e)
        {
            var dataTransfer = (SocketEvent)e;
            var compData = dataTransfer.Data.Split(new char[] { ':' });
            switch (compData[0])
            {
                case "ERROR":
                    MessageBox.Show(compData[1], "Error", MessageBoxButtons.OK);
                    break;
                case "NOTIFY":
                    if (compData[1].Equals("WAITOPPONENT"))
                    {
                        WriteStatus("Waiting for opponent");
                    }
                    else if (compData[1].Equals("STARTGAME"))
                    {
                        WriteStatus("Starting game");
                        StartGame();
                    }
                    break;
                case "MAXIMUMCONNECTION":
                    // Disconnect from server
                    if (this.m_socClient != null)
                    {
                        this.m_socClient.SocClient.Close();
                        this.m_socClient = null;
                    }
                    EnableStart(true);
                    WriteStatus("Waiting for start...");
                    MessageBox.Show("Maximun connection", "Error", MessageBoxButtons.OK);
                    break;
            }
        }

        private void EnableStart(bool enable)
        {
            if (btnStart.InvokeRequired)
            {
                EnableStartGameDel del = new EnableStartGameDel(EnableStart);
                btnStart.Invoke(del, new object[] { enable });
                return;
            }
            btnStart.Enabled = enable;
        }

        /// <summary>
        /// Show playing game
        /// </summary>
        private void StartGame()
        {
            if (this.InvokeRequired)
            {
                StartGameDel del = new StartGameDel(StartGame);
                this.Invoke(del, new object[] { });
                return;
            }
            this.Hide();

            FrmPlayGame frm = new FrmPlayGame
            {
                SocClient = m_socClient,
                PlayerName = txtPlayerName.Text.Trim()
            };
            frm.ShowDialog(this);
            this.Close();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        /// <summary>
        /// Validate input by user such as port and server address
        /// </summary>
        /// <returns>true: valid and false: invalid</returns>
        private bool ValidateInputs(ref string errTxt)
        {
            if (txtServerAddress.Text == string.Empty)
            {
                errTxt = "Server address is empty";
                return false;
            }
            if (txtServerPort.Text == string.Empty)
            {
                errTxt = "Server port is empty";
                return false;
            }
            int n;
            if (!int.TryParse(txtServerPort.Text, out n))
            {
                errTxt = "Server port must be numeric";
                return false;
            }
            return true;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            var errTxt = string.Empty;
            if (!ValidateInputs(ref errTxt))
            {
                MessageBox.Show(errTxt, "Error", MessageBoxButtons.OK);
                return;
            }

            if (this.m_socClient == null)
            {
                this.m_socClient = new AsyncSocket();
                m_socClient.ConnectHandler += HandleSocketEvent;
            }
            if (this.m_socClient.Connect(txtServerAddress.Text.Trim(), txtServerPort.Text.Trim(), txtPlayerName.Text.Trim()))
            {
                EnableStart(false);
            }
            else
            {
                EnableStart(true);
            }
        }

        /// <summary>
        /// Write log status
        /// </summary>
        /// <param name="data"></param>
        private void WriteStatus(string data)
        {
            if (lblStatus.InvokeRequired)
            {
                WriteStatusDel del = new WriteStatusDel(WriteStatus);
                lblStatus.Invoke(del, new object[] { data });
                return;
            }
            lblStatus.Text = data;
        }

        private void FrmConfiguration_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (m_socClient != null)
            {
                this.m_socClient.Disconnect(txtPlayerName.Text.Trim());
            }
        }
    }
}
